﻿using System;

using System.Management.Automation;
using CrystalDecisions.Enterprise;


namespace BO.Management.PowerShell
{
    [Cmdlet(VerbsCommon.Move, "BoeObject", DefaultParameterSetName = CONNECT_SECWINAD)]
    public class MoveObject : BaseGetObject<ContentGenericProvider, CrystalDecisions.Enterprise.InfoObject>
    {

        [Parameter(ValueFromPipeline = true)]
        public Int32? DestinationId { get; set; }

        [Parameter(ValueFromPipeline = true)]
        public String DestinationPath { get; set; }

        private InfoObject DestinationObject;

        /// <summary>
        /// Get a content genric provider to be able to move any kind of bo objects
        /// </summary>
        /// <returns></returns>
        public override ContentGenericProvider GetProvider()
        {
            return new ContentGenericProvider(this.LogonProvider);
        }

        protected override void BeginProcessing()
        {
            base.BeginProcessing();
        }

        /// <summary>
        /// Determine the destination Folder
        /// </summary>
        private void DetermineDestinationFolder()
        {
            Boolean isWildCard = false;

            if (this.DestinationId.HasValue)
            {
                WriteVerbose(String.Format("Search the destination folder with id {0}", this.DestinationId));
                DestinationObject = this.ProcessById(this.DestinationId.Value);
            }
            else if (!string.IsNullOrEmpty(this.DestinationPath))
            {
                WriteVerbose(String.Format("Search the destination folder with path {0}", this.DestinationPath));
                DestinationObject = BoeProvider.GetObjectFromPath(this.DestinationPath, out isWildCard);
                if (isWildCard)
                {
                    WriteVerbose(String.Format("Wildcard is not supported in the destination path {0}", this.DestinationPath));
                    ThrowTerminatingError(new ErrorRecord(new NotSupportedException(String.Format("Wildcard is not supported in the destination path {0}", this.DestinationPath)),
                                           "INVALIDARG", ErrorCategory.InvalidArgument, null));
                }
            }
        }


        /// <summary>
        /// Move the bo object to its destination
        /// </summary>
        /// <param name="boeObject"></param>
        public override void WorkWithSingleObject(CrystalDecisions.Enterprise.InfoObject boeObject)
        {
            if (DestinationObject == null)
            {
                this.DetermineDestinationFolder();
                if (DestinationObject == null ||
                    (DestinationObject.Kind != Enum.GetName(typeof(ObjectKind), ObjectKind.ObjectPackage) &
                    DestinationObject.Kind != Enum.GetName(typeof(ObjectKind), ObjectKind.Folder)))
                {
                    WriteVerbose(String.Format("Unable to find a folder with id {0}", this.DestinationId));
                    Console.WriteLine(String.Format("Unable to find a folder with id {0}", this.DestinationId));
                    return;
                }
            }

            WriteVerbose(String.Format("Move {0} to folder {1}", boeObject.Title, DestinationObject.Title));
            boeObject.ParentID = this.DestinationObject.ID;
            BoeProvider.Commit(boeObject);
            Console.WriteLine(String.Format("{0} has been moved to folder {1}", boeObject.Title, DestinationObject.Title));
        }

        /// <summary>
        /// As move object is change ParentID, we don't have to reccursive search. Chnaging the first level is ok
        /// </summary>
        /// <param name="parentId"></param>
        /// <param name="reccurse"></param>
        /// <param name="nbLevels"></param>
        /// <returns></returns>
        protected override void ProcessHierarchical(bool recurse, int depth)
        {
            this.ProcessHierarchical(BoeProvider, false, 1);
        }
    }
}
